////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "WNMemory/inc/WNMemory.h"
#include "WNScripting/inc/WNExpressionList.h"
#include "WNScripting/inc/WNExpression.h"

WNExpressionList::WNExpressionList(WN_SIZE_T _startLine,
                                   WN_SIZE_T _endLine,
                                   WN_SIZE_T _startChar,
                                   WN_SIZE_T _endChar,
                                   WNExpression* _expr) :
    WNParseNode(_startLine, _endLine, _startChar, _endChar),
    mExpression(_expr),
    mSubList(WN_NULL) {
}

WNExpressionList::WNExpressionList(WN_SIZE_T _startLine,
                                   WN_SIZE_T _endLine,
                                   WN_SIZE_T _startChar,
                                   WN_SIZE_T _endChar,
                                   WNExpressionList* _exprList,
                                   WNExpression* _expr) :
    WNParseNode(_startLine, _endLine, _startChar, _endChar),
    mExpression(_expr),
    mSubList(_exprList) {
}

WNExpressionList::~WNExpressionList() {
    if (mSubList != WN_NULL) {
        WN_DELETE(mSubList);
    }
    if (mExpression != WN_NULL) {
        WN_DELETE(mExpression);
    }
}

llvm::Value* WNExpressionList::OptimizeAndGenerate(WNScriptingEngineData& _scriptingData, WNFunctionDecl* _functionDecl) {
    WN_DEBUG_ASSERT(mExpression);
    OptimizeAndGeneratePrivate(_scriptingData, _functionDecl, mExpressions);
    return(WN_NULL);
}

void WNExpressionList::OptimizeAndGeneratePrivate(WNScriptingEngineData& _scriptingData, WNFunctionDecl* _functionDecl, std::vector<WNExpressionListVal>& _fillList) {
    WNParseNode::OptimizeAndGenerate(_scriptingData, _functionDecl);
    WN_DEBUG_ASSERT(mExpression);
    llvm::Value* val = mExpression->OptimizeAndGenerate(_scriptingData, _functionDecl);

    WNExpressionListVal v = { mExpression, val };
    
    mExpression = WN_NULL;
    if (mSubList) {
        mSubList->OptimizeAndGeneratePrivate(_scriptingData, _functionDecl, _fillList);
    }
    _fillList.push_back(v);

    WN_DELETE(mSubList);
    mSubList = WN_NULL;
}

void WNExpressionList::GetExpressions(std::vector<WNExpressionList::WNExpressionListVal>& _outList) const {
    WN_DEBUG_ASSERT(mOptimized);
    _outList.assign(mExpressions.begin(), mExpressions.end());
}